<?php
/**
 * Radcodes - SocialEngine Module
 *
 * @category   Application_Extensions
 * @package    Game
 * @copyright  Copyright (c) 2009-2010 Radcodes LLC (http://www.radcodes.com)
 * @license    http://www.radcodes.com/license/
 * @version    $Id$
 * @author     Vincent Van <vincent@radcodes.com>
 */
class Game_Model_DbTable_Scores extends Engine_Db_Table
{
  protected $_rowClass = 'Game_Model_Score';
  
  
  public function preloadUsers($scores)
  {
    $user_ids = array();
    foreach ($scores as $score)
    {
      $users_ids[$score->user_id] = $score->user_id;
    }
    
    if (count($user_ids)) {
      Engine_Api::_()->user()->getUserMulti($user_ids);
    }
    
    return $user_ids;
  }
  
  public function getGameScores(Game_Model_Game $game, $params = array())
  {
    $params = array_merge(array('game'=>$game, 'order'=>'score'), $params);
    $select = $this->getScoreSelect($params);
    
    if (isset($params['limit'])) {
      $select->limit($params['limit']);
    }
    //$select->group('user_id');
    //echo $select;
    
    //echo "<br>";
    //echo $this->getGameHighScores($game, $params);
    
    return $this->fetchAll($select);
  }
  
  
  public function getGameHighScores(Game_Model_Game $game, $params = array())
  {
    $select = new Zend_Db_Select($this->getAdapter());
    $select->from($this->info('name'), array(
      'user_id',
      'MAX(score) as score'
    ));
    $select->where("game_id = ?", $game->getIdentity());
    //$select->where("game_id = 999");
    $select->group("user_id");
    $select->order('MAX(score) DESC');
    
    if (isset($params['limit'])) {
      $select->limit($params['limit']);
    }    
    
    //echo $select;

    $rows = $select->query()->fetchAll();
    $ds = array();
    if (empty($rows))
    {
      return $ds;
    }
    
    
    foreach ($rows as $row) {
      $ds[] = "(user_id='{$row['user_id']}' AND score='{$row['score']}')";
    }
    
    $params = array_merge(array('game'=>$game, 'order'=>'score'), $params);
    $select = $this->getScoreSelect($params);
    $select->where(join(" OR ", $ds));
    
    if (isset($params['limit'])) {
      $select->limit($params['limit']);
    }
    
    //echo $select;
    return $this->fetchAll($select);
    
  }
  
  /**
   * @return Zend_Paginator
   */
  public function getScorePaginator($params = array())
  {
    $paginator = Zend_Paginator::factory($this->getScoreSelect($params));
    
    if( !empty($params['page']) )
    {
      $paginator->setCurrentPageNumber($params['page']);
    }
    if( !empty($params['limit']) )
    {
      $paginator->setItemCountPerPage($params['limit']);
    }    
    
    return $paginator;
  }
  
  /**
   * @return Zend_Db_Table_Select
   */
  public function getScoreSelect($params = array())
  {
    return $this->selectParamBuilder($params);
  }
  
  
  /**
   * @return Zend_Db_Table_Select
   */  
  public function selectParamBuilder($params = array(), $select = null)
  {
    $rName = $this->info('name');
    
    if ($select === null)
    {
      $select = $this->select();
    }
    
    if (isset($params['user']) && $params['user']) 
    {
      $user = Engine_Api::_()->user()->getUser($params['user']);
      $select->where($rName.'.user_id = ?', $user->getIdentity());
    }
    if (isset($params['users']) && is_array($params['users']) ) {
      $users = array();
      foreach( $params['users'] as $user_id ) {
        if( is_int($user_id) && $user_id > 0 ) {
          $users[] = $user_id;
        }
      }
      if( empty($users) ) {
        return $select->where('1 != 1');
      } else {
        $select->where($rName.'.user_id IN (?)', $users);
      }
    }
    
    if (isset($params['game']) && $params['game']) 
    {
      $game_id = ($params['game'] instanceof Core_Model_Item_Abstract) ? $params['game']->getIdentity() : $params['game'];
      $select->where($rName.'.game_id = ?', $game_id);
    }
    
    foreach (array('sort_order', 'score_label', 'score', 'datatype', 'board_id', 'game_tag') as $field)
    {
      if (isset($params[$field]))
      {
        $select->where($rName.".$field = ?", $params[$field]);
      }
    }
    
    if( !empty($params['start_date']) )
    {
      $select->where($rName.".creation_date >= ?", date('Y-m-d', $params['start_date']));
    }

    if( !empty($params['end_date']) )
    {
      $select->where($rName.".creation_date <= ?", date('Y-m-d', $params['end_date']));
    }
    
    if( !empty($params['period']))
    {
      $period_maps = array(
        '24hrs' => 1,
        'week' => 7,
        'month' => 30,
        'quarter' => 120,
        'year' => 365,
      );
      if (isset($period_maps[$params['period']]) && $period_maps[$params['period']])
      {
        $select->where($rName.".creation_date >= ?", date('Y-m-d', time() - $period_maps[$params['period']] * 86400));
      }
    }   

    if (isset($params['order'])) 
    {
      switch ($params['order'])
      {
        case 'random':
          $order_expr = new Zend_Db_Expr('RAND()');
          break;
        case 'recent':
          $order_expr = $rName.".creation_date DESC";
          break;
        case 'lastupdated':
          $order_expr = $rName.".modified_date DESC";
          break;
        case 'score':
          $order_expr = $rName.".score DESC";
          break;

        case 'score_asc':
          $order_expr = $rName.".score ASC";
          break;
          
        default:
          $order_expr = !empty($params['order']) ? $params['order'] : $rName.'.creation_date DESC';
          
          if (!empty($params['order_direction'])) {
            $order_expr .= " " .$params['order_direction'];
          }
          
          if (!is_array($order_expr) && !($order_expr instanceof Zend_Db_Expr) and strpos($order_expr, '.') === false) {
            $order_expr = $rName.".".trim($order_expr);
          }
          break;
      }    
      $select->order( $order_expr );
      unset($params['order']);
    }
    //echo $select;
    return $select;
  }
  
  
  public function countScores($params = array())
  {
    $select = $this->select()->from($this, new Zend_Db_Expr('COUNT(score_id)'));
    $select = $this->selectParamBuilder($params, $select)->limit(1);
    //echo $select;
    $total = $select->query()->fetchColumn();
    return $total;
  }  
  
}
